<template>
  <div class="avatar-container">
    <div ref="avatarWrapper" class="avatar-wrapper"></div>
    <div v-if="isRecording" class="recording-indicator">
      <div class="recording-wave"></div>
      <span>录音中...</span>
    </div>
    <div class="recognized-text">识别结果：{{ recognizedText }}</div>
    <div class="control-panel">
      <input v-model="inputText" type="text" placeholder="请输入文字..." @keyup.enter="sendText" />
      <button @click="sendText">发送</button>
      <div
        class="record-button"
        :class="{ recording: isRecording }"
        @touchstart.prevent="startRecord"
        @touchend.prevent="stopRecord"
        @mousedown.prevent="startRecord"
        @mouseup.prevent="stopRecord"
        @mouseleave.prevent="stopRecord"
      >
        <i class="microphone-icon"></i>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, onUnmounted } from 'vue';
import AvatarPlatform, { PlayerEvents, SDKEvents } from './avatar-sdk-web_3.1.2.1002/index.js';
import { avatarConfig } from './config';

interface InitResponse {
  [key: string]: unknown;
}

interface ErrorType {
  message: string;
  code?: number;
  [key: string]: unknown;
}

const avatarWrapper = ref<HTMLDivElement>();
const inputText = ref('');
let avatarPlatform: AvatarPlatform | null = null;

// 添加录音状态
const isRecording = ref(false);

// 添加语音识别结果状态
const recognizedText = ref('');

// 添加录音配置
const audioConfig = ref({
  nlp: true, // 是否启用语义理解
  fullDuplex: true, // 是否使用全双工模式
  singleSeconds: 20, // 单轮模式下的自动停止时间
});

// 初始化虚拟人平台
const initAvatarPlatform = async () => {
  try {
    // 创建实例
    avatarPlatform = new AvatarPlatform();

    // 设置事件监听
    setupEventListeners();

    // 设置API信息
    avatarPlatform.setApiInfo({
      appId: avatarConfig.appId,
      apiKey: avatarConfig.apiKey,
      apiSecret: avatarConfig.apiSecret,
      sceneId: avatarConfig.serviceId,
      serverUrl: avatarConfig.tdpUrl,
    });

    // 设置全局参数
    avatarPlatform.setGlobalParams({
      stream: {
        protocol: 'xrtc',
      },
      avatar: {
        avatar_id: avatarConfig.avatarId,
      },
      tts: {
        vcn: avatarConfig.vcn,
      },
      tdp: {
        url: avatarConfig.tdpUrl,
      },
    });

    // 拟人
    await avatarPlatform.start({
      wrapper: avatarWrapper.value,
    });

    console.log('虚拟人初始化成功');
  } catch (error) {
    console.error('虚拟人初始化失败:', error);
  }
};

// 设置事件监听
const setupEventListeners = () => {
  avatarPlatform
    .on(SDKEvents.connected, (initResp: InitResponse) => {
      console.log('连接成功', initResp);
    })
    .on(SDKEvents.stream_start, () => {
      console.log('流开始');
    })
    .on(SDKEvents.disconnected, (err: ErrorType) => {
      console.log('连接断开', err);
    })
    .on(SDKEvents.error, (error: ErrorType) => {
      console.error('错误:', error);
    })
    .on(SDKEvents.asr, (asrData: any) => {
      console.log('语音识别(ASR)结果:', asrData);
      // ASR 结果可能会多次返回，实时更新
      if (asrData?.text) {
        recognizedText.value = `[ASR] ${asrData.text}`;
      }
    })
    .on(SDKEvents.nlp, (nlpData: any) => {
      console.log('语义理解(NLP)结果:', nlpData);
      if (nlpData?.text) {
        recognizedText.value = `[NLP] ${nlpData.text}`;
      }
    })
    .on(SDKEvents.recorder_start, () => {
      console.log('录音器开始工作');
    })
    .on(SDKEvents.recorder_stop, () => {
      console.log('录音器停止工作');
    })
    .on(SDKEvents.tts_duration, (data: any) => {
      console.log('TTS 时长:', data);
    })
    .on(SDKEvents.frame_start, (data: any) => {
      console.log('帧开始:', data);
    })
    .on(SDKEvents.frame_stop, (data: any) => {
      console.log('帧结束:', data);
    });
};

// 发送文本
const sendText = async () => {
  if (!inputText.value) return;
  try {
    await avatarPlatform.writeText(inputText.value, {
      nlp: true,
    });
    inputText.value = '';
  } catch (error) {
    console.error('发送文本失败:', error);
  }
};

// 开始录音
const startRecord = async () => {
  if (!avatarPlatform) {
    console.error('SDK 未初始化');
    return;
  }

  try {
    console.log('开始请求麦克风权限...');
    await navigator.mediaDevices?.getUserMedia({ audio: true });
    console.log('麦克风权限获取成功');

    // 检查录音器采样率是否正确
    if (avatarPlatform.recorder) {
      if (audioConfig.value.nlp && avatarPlatform.recorder.sampleRate !== 16000) {
        // 交互拾音只支持16k 16bit
        avatarPlatform.destroyRecorder();
      }
    }

    // 创建录音器
    if (!avatarPlatform.recorder) {
      avatarPlatform.createRecorder({
        sampleRate: 16000, // 交互必须使用 16k 采样率
      });
    }

    const recorder = avatarPlatform.recorder;
    if (!recorder) {
      throw new Error('录音器创建失败');
    }

    isRecording.value = true;
    console.log('录音状态:', isRecording.value);
    recognizedText.value = ''; // 清空上一次的识别结果

    // 开始录音
    recorder.startRecord(
      audioConfig.value.fullDuplex ? 0 : audioConfig.value.singleSeconds * 1000,
      () => {
        console.log('录音自动停止');
        isRecording.value = false;
      },
      {
        nlp: audioConfig.value.nlp,
      }
    );
    console.log('录音开始...');
  } catch (error) {
    console.error('开始录音失败:', error);
    isRecording.value = false;
  }
};

// 停止录音
const stopRecord = () => {
  if (!avatarPlatform) {
    console.error('SDK 未初始化');
    return;
  }

  console.log('准备停止录音...');
  if (!isRecording.value) {
    console.log('录音未开始，不需要停止');
    return;
  }

  try {
    const recorder = avatarPlatform.recorder;
    if (recorder) {
      console.log('正在停止录音...');
      recorder.stopRecord();
      console.log('录音已停止');
    }
  } catch (error) {
    console.error('停止录音失败:', error);
  } finally {
    isRecording.value = false;
  }
};

// 添加停止虚拟人函数
const stopAvatar = () => {
  if (!avatarPlatform) {
    console.error('SDK 未初始化');
    return;
  }
  avatarPlatform.stop();
};

onMounted(async () => {
  initAvatarPlatform();
});

// 组件卸载时清理
onUnmounted(() => {
  if (avatarPlatform) {
    avatarPlatform.stop();
    avatarPlatform.destroy();
  }
});
</script>

<style scoped>
.avatar-container {
  width: 100%;
  height: calc(100vh - 54px);
  display: flex;
  flex-direction: column;
  position: relative;
}

.avatar-wrapper {
  flex: 1;
  width: 100%;
  background-color: #000;
  position: relative;
}

.control-panel {
  width: 100%;
  padding: 8px;
  background-color: #fff;
  display: flex;
  gap: 8px;
  box-sizing: border-box;
}

.control-panel input {
  flex: 1;
  height: 30px;
  padding: 0 12px;
  border: 1px solid #ddd;
  border-radius: 4px;
  font-size: 12px;
}

.control-panel button {
  height: 30px;
  padding: 0 16px;
  border: none;
  border-radius: 4px;
  background-color: #1890ff;
  color: #fff;
  font-size: 12px;
  cursor: pointer;
}

.control-panel button:active {
  opacity: 0.8;
}

.record-button {
  height: 30px;
  width: 40px;
  padding: 0;
  border: none;
  border-radius: 4px;
  background-color: #1890ff;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  user-select: none;
  transition: all 0.2s;
}

.record-button:active,
.record-button.recording {
  background-color: #ff4d4f;
}

.microphone-icon {
  width: 20px;
  height: 20px;
  background-image: url('');
  background-repeat: no-repeat;
  background-position: center;
  background-size: contain;
}


.recording-indicator {
  position: fixed;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  background: rgba(0, 0, 0, 0.7);
  padding: 20px 40px;
  border-radius: 40px;
  color: white;
  display: flex;
  align-items: center;
  gap: 12px;
  z-index: 1000;
}

.recording-wave {
  width: 20px;
  height: 20px;
  background: #ff4d4f;
  border-radius: 50%;
  animation: wave 1s infinite ease-in-out;
}

@keyframes wave {
  0% {
    transform: scale(0.8);
    opacity: 0.5;
  }
  50% {
    transform: scale(1.2);
    opacity: 1;
  }
  100% {
    transform: scale(0.8);
    opacity: 0.5;
  }
}

.recognized-text {
  padding: 0 16px;
  background: #f5f5f5;
  border: 1px solid #e8e8e8; /* 改为实线边框 */
  color: #333;
  font-size: 14px;
  line-height: 1.5;
  word-break: break-all;
  border-radius: 4px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
  height: 24px;
}

/* 当没有文本时隐藏 */
.recognized-text:empty {
  display: none;
}
</style>
